package com.cs.framework.web.handler.support;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.cs.framework.common.util.CommonUtils;
import com.cs.framework.common.util.StringUtils;
import com.cs.framework.core.context.Application;
import com.cs.framework.core.context.Module;
import com.cs.framework.web.context.ActionContext;
import com.cs.framework.web.context.WebModule;
import com.cs.framework.web.exception.WebExceptionHelper;
import com.cs.framework.web.handler.Handler;
import com.cs.framework.web.handler.HandlerMethod;
import com.cs.framework.web.handler.Web;
import com.cs.framework.web.util.RequestUtils;
import com.cs.framework.web.view.DefaultViewName;
import com.cs.framework.web.view.ViewInfo;

/**
 * Action处理器
 * 
 * @author hedongzhou
 * 
 */
public class ActionHandler implements Handler {

	private final Log logger = LogFactory.getLog(getClass());

	/**
	 * 存放访问Action方法的映射信息
	 */
	private Map<String, HandlerMethod> methodMap = new HashMap<String, HandlerMethod>();

	/**
	 * 初始化
	 * 
	 * @param application
	 *            应用上下文
	 */
	public void init(Application application) {
		// 获取所有的模块ID
		Set<String> moduleIdSet = application.getModuleIdSet();
		for (String moduleId : moduleIdSet) {
			// 获取Action对应的模块
			WebModule module = (WebModule) application.getModule(moduleId);

			// 添加映射信息
			methodMap.putAll(module.getMethodMap());
		}
	}

	/**
	 * 判断是否可以处理请求
	 * 
	 * @param request
	 * @return
	 */
	public boolean canHandler(HttpServletRequest request) {
		String suffix = RequestUtils.getSuffix(request);

		return CommonUtils.isEmpty(suffix) || StringUtils.equalOne(suffix, ".do");
	}

	/**
	 * 处理请求
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	public ViewInfo handler(HttpServletRequest request, HttpServletResponse response) {
		ViewInfo viewInfo = null;

		// 获取资源路径
		String resourcePath = RequestUtils.getResourceNoSuffix(request);
		// 获取映射信息
		HandlerMethod handlerMethod = methodMap.get(resourcePath);
		if (handlerMethod == null) {
			WebExceptionHelper.throwWebException("W005", resourcePath);
		}

		// 获取相关信息
		Module module = handlerMethod.getModule();
		Object actionBean = handlerMethod.getActionBean();
		Method actionMethod = handlerMethod.getActionMethod();

		// 设置上下文环境
		ActionContext handlerContext = new ActionContext(module, request, response);
		Web.setHandlerContext(handlerContext);
		try {
			// 调用方法
			Object data = actionMethod.invoke(actionBean);

			// 获取视图信息
			viewInfo = Web.getViewInfo();

			if (data != null) {
				viewInfo.getViewData().addAttribute(data);
			}

			if (RequestUtils.isAjax(request)) {
				viewInfo.setViewName(DefaultViewName.JSON_VIEW);
			}
		} catch (IllegalArgumentException e) {
			logger.error(e.getMessage(), e);
			WebExceptionHelper.throwWebException(e, "W006", actionBean.getClass().getName(), actionMethod.getName());
		} catch (IllegalAccessException e) {
			logger.error(e.getMessage(), e);
			WebExceptionHelper.throwWebException(e, "W007", actionBean.getClass().getName(), actionMethod.getName());
		} catch (InvocationTargetException e) {
			logger.error(e.getMessage(), e);
			WebExceptionHelper.throwWebException(e, "W008", actionBean.getClass().getName(), actionMethod.getName());
		} finally {
			Web.remove();
		}

		return viewInfo;
	}

}
